home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 280_01 / archive.c < prev    next >
Text File  |  1989-01-11  |  8KB  |  399 lines

  1. /* [ARCHIVE.C of JUGPDS Vol.46] */
  2. /*
  3. *****************************************************************
  4. *                                *
  5. *    Written by  Hakuo Katayose (JUG-CP/M No.179)        *
  6. *            49-114 Kawauchi-Sanjuunin-machi        *
  7. *            Sendai, Miyagi 980                          *
  8. *            Phone: 0222-61-3219                *
  9. *                                *
  10. *       Modifird by Toshiya Oota   (JUG-CPM No.10)              *
  11. *                   Sakae ko-po 205                 *
  12. *            5-19-6 Hosoda                *
  13. *            Katusikaku Tokyo 124            *
  14. *                                *
  15. *        for MS-DOS Lattice C V3.1J & 80186/V20/V30    *
  16. *                                *
  17. *    Compiler Option: -ccu -k0(1) -ms -n -v -w        *
  18. *                                *
  19. *    Edited & tested by Y. Monma (JUG-CP/M Disk Editor)    *
  20. *            &  T. Ota   (JUG-CP/M Sub Disk Editor)    *
  21. *                                *
  22. *****************************************************************
  23. */
  24.  
  25. /* Library functions for Software Tools */
  26.  
  27. #include "stdio.h"
  28. #include "dos.h"
  29. #include "ctype.h"
  30. #include "tools.h"
  31.  
  32. /* archive - file maintaner */
  33.  
  34. #define    UPD    'u'
  35. #define    TBL    't'
  36. #define    EXTR    'x'
  37. #define    PRINT    'p'
  38. #define    DEL    'd'
  39.  
  40. #define    MAXFILES    8
  41. #define    NAMESIZE    16
  42. #define    MAXCHARS    32000
  43.  
  44. #define    makhdr(name, head)    sprintf(head,"-h- %s %d\n", name, fsize(name))
  45.  
  46. char    fname[MAXFILES][NAMESIZE];
  47. int    fstat[MAXFILES], nfiles, errcnt;
  48.  
  49. void    getfns(),update(),table(),extrac(),delete();
  50. void    fskip(),acopy(),addfil(),amove(),fcopy(),cant(),notfnd();
  51.  
  52. void main(argc, argv)
  53. int    argc;
  54. char     *argv[];
  55.  
  56. {
  57. char    aname[NAMESIZE], cmd;
  58.  
  59.     if (argc < 3) {
  60.         error("ARC901 Usage: archive {dptux} archname [files]");
  61.         exit(1);
  62.         }
  63.     strcpy(aname, argv[2]);
  64.     getfns(argc, argv);
  65.     if ((cmd = tolower(argv[1][0])) == UPD)
  66.         update(aname);
  67.     else if (cmd == TBL)
  68.         table(aname);
  69.     else if (cmd == PRINT || cmd == EXTR)
  70.         extrac(aname, cmd);
  71.     else if (cmd == DEL)
  72.         delete(aname);
  73.     else
  74.         error("ARC902 Option error: use only {dptux} .");
  75. }
  76.  
  77. /* getfns -get file names, check for duplicates */
  78.  
  79. void getfns(argc, argv)
  80. char *argv[];
  81.  
  82. {
  83. int    i, j;
  84.  
  85.     errcnt = 0;
  86.     nfiles = argc - 3;
  87.     if (nfiles > MAXFILES)
  88.         error("ARC911 Too many file names!");
  89.     for (i = 0; i < nfiles; i++) {
  90.         strcpy(fname[i], argv[i+3]);
  91.         fstat[i] = NO;
  92.     }
  93.     for (i = 0; i < nfiles - 1; i++)
  94.         for (j = i + 1; j < nfiles; j++)
  95.             if (!strcmp(fname[i], fname[j]))
  96.                 fprintf(STDERR,"ARC912 %s: duplicate file name."                                  ,fname[i]);
  97. }
  98.  
  99. /* update - update existing files, add new ones at end */
  100. void    update(aname)
  101. char    *aname;
  102.  
  103. {
  104. FILE    *afd,*tfd;
  105. char    *tname;
  106. int    i;
  107. void    replac();
  108.  
  109.     tname = "archtemp.$$$";
  110.     if ((afd = fopen(aname, "r")) == NO)
  111.         cant(aname);
  112.     if ((tfd = fopen(tname, "w")) == NO)
  113.         cant(tname);
  114.     replac(afd, tfd, UPD, &errcnt);
  115.     for (i = 0; i < nfiles; i++)
  116.         if (fstat[i] == NO) {
  117.             addfil(fname[i], tfd, &errcnt);
  118.             fstat[i] = YES;
  119.         }
  120.     fclose(afd);
  121.     putc(CPMEOF, tfd);
  122.     fclose(tfd);
  123.     if (!errcnt)
  124.         amove(tname, aname);
  125.     else
  126.         remark("ARC913 Fatal errors - archive not altered.");
  127.     unlink(tname);
  128. }
  129.  
  130. /* replac - replace or delete files */
  131. void replac(afd, tfd, cmd, errcnt)
  132. FILE    *afd, *tfd;
  133. int    *errcnt;
  134.  
  135. {
  136. char    in[MAXLINE], uname[NAMESIZE];
  137. int    size;
  138.  
  139.     while (gethdr(afd, in, uname, &size) != EOF)
  140.         if (filarg(uname) == YES) {
  141.             if (cmd == UPD)    
  142.                 addfil(uname, tfd, errcnt);
  143.             fskip(afd, size);
  144.         } else {
  145.             fputs(in, tfd);
  146.             acopy(afd, tfd, size);
  147.         }
  148. }
  149.  
  150. /* gethdr - get header info from fd */
  151. int    gethdr(fd, buf, name, size)
  152. FILE    *fd;
  153. char    buf[MAXLINE], name[NAMESIZE];
  154. int    *size;
  155.  
  156. {
  157. int    len, i;
  158. char    temp[NAMESIZE];
  159.  
  160.     if (fgetlin(fd,buf,MAXLINE) == NULL)
  161.         return (EOF);
  162.     i = 0;
  163.     len = getwrd(buf, &i, temp);
  164.     if (strcmp(temp, "-h-"))
  165.         error("ARC914 archive not in proper format.");
  166.     len = getwrd(buf, &i, name);
  167.     *size = atoi(buf+i);
  168.     return YES;
  169. }
  170.  
  171. /* fskip - skip n characters on file fd */
  172. void fskip(fd, n)
  173. FILE    *fd;
  174. int    n;
  175. {
  176. int    c;
  177.  
  178.     while (n--)
  179.         if ((c = getc(fd)) == EOF || c == CPMEOF)
  180.             break;
  181. }
  182.  
  183. /* filarg - check if namematches argument list */
  184. int    filarg(name)
  185. char    *name;
  186.  
  187. {
  188. int    i;
  189.  
  190.     if (nfiles <= 0)
  191.           return (YES);
  192.     for (i = 0; i < nfiles; i++) {
  193.         if (!strcmp(name, fname[i])) {
  194.             fstat[i] = YES;
  195.             return (YES);
  196.              }
  197.     }
  198.     return (NO);
  199. }
  200.  
  201. /* acopy - copy size characters from fdi to fdo */ 
  202. void    acopy(fdi, fdo, size)
  203. FILE    *fdi, *fdo;
  204. int    size;
  205. {
  206. int    c;
  207.  
  208.     while (size--) {
  209.         if ((c = getc(fdi)) == EOF || c == CPMEOF)
  210.                     break;
  211.         putc(c, fdo);
  212.         }
  213. }
  214.  
  215. /* addfil - add file "name" to archive */
  216. void    addfil(name, fd, errcnt)
  217. char    *name;
  218. FILE    *fd;
  219. int    *errcnt;
  220.  
  221. {
  222. char    head[MAXLINE];
  223. FILE    *nfd;
  224.  
  225.     if ((nfd = fopen(name, "r")) == NO) {
  226.         fprintf(STDERR, "ARC915 %s:  can't add.", name);
  227.         (*errcnt)++;
  228.     }
  229.     if (!*errcnt) {
  230.         makhdr(name, head);
  231.         fputs(head, fd);
  232.         fcopy(nfd, fd);
  233.         fclose(nfd);
  234.     }
  235. }
  236.  
  237. /* amove - move file1 to file2 */
  238. void amove(file1, file2)
  239. char *file1, *file2;
  240.  
  241. {
  242. FILE    *fp1, *fp2;
  243.  
  244.     if ((fp1 = fopen(file1,"r" )) == NO)
  245.         cant(file1);
  246.     else if ((fp2 = fopen(file2, "w")) == NO)
  247.         cant(file2);
  248.  
  249.     fcopy(fp1, fp2);
  250.  
  251.     fclose(fp1);
  252.     putc(CPMEOF,fp2);
  253.     fclose(fp2);
  254. }
  255.  
  256. /* fcopy - copy file fp1 to fle fp2 */
  257. void fcopy(fp1, fp2)
  258. FILE *fp1, *fp2;
  259.  
  260. {
  261. int c;
  262.  
  263.     while ((c = getc(fp1)) != EOF && c != CPMEOF)
  264.         putc(c,fp2);
  265. }
  266.  
  267. /* cant - can't open file, exit to CP/M */
  268. void cant(fname)
  269. char *fname;
  270.  
  271. {
  272.     fprintf(STDERR, "ARC916 can't open %s\n", fname);
  273.     exit(1);
  274. }
  275.  
  276. /* fsize - size of file in characters */
  277. int    fsize(name)
  278. char    *name;
  279.  
  280. {
  281. int    size;
  282. FILE    *fp;
  283. int    c;
  284.  
  285.     if ((fp = fopen(name,"r")) == NO)
  286.         return ERROR;
  287.     else {
  288.         for (size = 0; (c = getc(fp)) != EOF && c != CPMEOF; size++)
  289.             ;
  290.         fclose(fp);
  291.         return size;
  292.     }
  293. }
  294.  
  295. /* table - print table of archive contents */
  296. #define    tprint(buf)    (fputs(buf, STDOUT))
  297.  
  298. void    table(aname)
  299. char    *aname;
  300.  
  301. {
  302. FILE    *afd;
  303. char    in[MAXLINE], lname[NAMESIZE];
  304. int    size;
  305.  
  306.     if ((afd = fopen(aname,"r")) == NO)
  307.         cant(aname);
  308.     while (gethdr(afd, in, lname, &size) != EOF) {
  309.         if (filarg(lname) == YES)
  310.             tprint(in);
  311.         fskip(afd, size);
  312.     }
  313.     notfnd();
  314.     fclose(afd);
  315. }
  316.  
  317. /* extract - extract files from archive */ 
  318. void    extrac(aname, cmd)
  319. char    *aname;
  320.  
  321. {
  322. FILE    *afd, *efd ,*fd;
  323. char    in[MAXLINE], ename[NAMESIZE];
  324. int    size;
  325.  
  326.     if ((afd =fopen(aname,"r")) == NO)
  327.         cant(aname);
  328.     if (cmd == PRINT)
  329.         fd =  STDOUT;
  330.     else
  331.         fd =  NO;
  332.     while (gethdr(afd, in, ename, &size) != EOF)
  333.         if (filarg(ename) == NO)
  334.             fskip(afd, size);
  335.         else {
  336.             if (fd != STDOUT)
  337.                 efd = fd = fopen(ename,"w+");
  338.             if (fd == NO) {
  339.                 fprintf(STDERR,"ARC917 %s:  can't create."
  340.                           , ename);
  341.                 errcnt++;
  342.                 fskip(afd, size);
  343.                 }
  344.             else {
  345.                 if (fd == STDOUT) {
  346.                     acopy(afd, STDOUT, size);
  347.                 }
  348.                 else
  349.                     acopy(afd, efd, size);
  350.                 if (fd != STDOUT)
  351.                     fclose(efd);
  352.                 }
  353.             }
  354.     notfnd();
  355. }
  356.  
  357. /* delete - delete files from archive */
  358. void    delete(aname)
  359. char    *aname;
  360.  
  361. {
  362. FILE    *afd, *tfd;
  363. char    *tname;
  364.  
  365.  
  366.     tname = "archtemp";
  367.  
  368.     if (nfiles <= 0)
  369.         error("ARC918 delete by name only.");
  370.     if ((afd = fopen(aname,"r")) == NO)
  371.         cant(aname);
  372.     if ((tfd = fopen(tname,"w+")) == NO)
  373.         cant(tname);
  374.     replac(afd, tfd, DEL, &errcnt);
  375.     notfnd();
  376.     fclose(afd);
  377.     putc(CPMEOF, tfd);
  378.     fclose(tfd);
  379.     if (errcnt == 0)
  380.         amove(tname, aname);
  381.     else
  382.         remark("ARC919 Fatal errors - archive not altered.");
  383.     unlink(tname);
  384. }
  385.  
  386. /* notfnd - not found */ 
  387. void notfnd()
  388.  
  389. {
  390. int    i;
  391.  
  392.     for (i = 0; i < nfiles; i++)
  393.         if (fstat[i] == NO) {
  394.             fprintf(STDERR,"ARC920 %s:  not in archive."
  395.                       , fname[i]);
  396.             errcnt++;
  397.             }
  398. }
  399.